#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2017 Baidu.com, Inc. All Rights Reserved
#

"""
File: common.py
Author: zhangyang(zhangyang40@baidu.com)
Date: 2017/10/12 下午1:49
"""
import csv
import hashlib
import math
import os
import subprocess

NR_BINS = 1000000


def hashstr(input):
    return str(int(hashlib.md5(input.encode('utf8')).hexdigest(), 16) % (NR_BINS - 1) + 1)


def open_with_first_line_skipped(path, skip=True):
    f = open(path)
    if not skip:
        return f
    next(f)
    return f


def split(path, nr_thread, has_header):
    def open_with_header_witten(path, idx, header):
        f = open(path + '.__tmp__.{0}'.format(idx), 'w')
        if not has_header:
            return f
        f.write(header)
        return f

    def calc_nr_lines_per_thread():
        nr_lines = int(list(subprocess.Popen('wc -l {0}'.format(path), shell=True,
                                             stdout=subprocess.PIPE).stdout)[0].split()[0])
        if not has_header:
            nr_lines += 1
        return math.ceil(float(nr_lines) / nr_thread)

    header = open(path).readline()

    nr_lines_per_thread = calc_nr_lines_per_thread()

    idx = 0
    f = open_with_header_witten(path, idx, header)
    for i, line in enumerate(open_with_first_line_skipped(path, has_header), start=1):
        if i % nr_lines_per_thread == 0:
            f.close()
            idx += 1
            f = open_with_header_witten(path, idx, header)
        f.write(line)
    f.close()


def parallel_convert(cvt_path, arg_paths, nr_thread):
    workers = []
    for i in range(nr_thread):
        cmd = '{0}'.format(os.path.join('.', cvt_path))
        for path in arg_paths:
            cmd += ' {0}'.format(path + '.__tmp__.{0}'.format(i))
        worker = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE)
        workers.append(worker)
    for worker in workers:
        worker.communicate()


def cat(path, nr_thread):
    if os.path.exists(path):
        os.remove(path)
    for i in range(nr_thread):
        cmd = 'cat {svm}.__tmp__.{idx} >> {svm}'.format(svm=path, idx=i)
        p = subprocess.Popen(cmd, shell=True)
        p.communicate()


def delete(path, nr_thread):
    for i in range(nr_thread):
        os.remove('{0}.__tmp__.{1}'.format(path, i))


def def_user(row):
    if row['device_id'] == 'a99f214a':
        user = 'ip-' + row['device_ip'] + '-' + row['device_model']
    else:
        user = 'id-' + row['device_id']

    return user


def def_user_hour(row):
    return def_user(row) + '-' + row['hour']


def is_app(row):
    return True if row['site_id'] == '85f751fd' else False


def has_id_info(row):
    return False if row['device_id'] == 'a99f214a' else True


def runcmd(cmd):
    subprocess.call(cmd, shell=True)


def read_prd(path):
    prd = {}
    for row in csv.DictReader(open(path)):
        prd[row['id']] = float(row['click'])
    return prd


def write_prd(prd, path):
    with open(path, 'w') as f:
        f.write('id,click\n')
        for id, click in sorted(prd.items()):
            f.write('{0},{1:.5f}\n'.format(id, click))
